package com.jumi.microservice.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jumi.microservice.common.constant.ResultEnum;
import com.jumi.microservice.common.exception.BaseException;
import com.jumi.microservice.common.redis.RedisCache;
import com.jumi.microservice.constant.*;
import com.jumi.microservice.domain.*;
import com.jumi.microservice.mapper.FreightTemplateExtendMapper;
import com.jumi.microservice.mapper.FreightTemplateMapper;
import com.jumi.microservice.mapper.GoodsMapper;
import com.jumi.microservice.mapper.GoodsSkuMapper;
import com.jumi.microservice.service.FreightTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 运费模板表 服务实现类
 * </p>
 *
 * @author liuz
 * @since 2020-07-27
 */
@Service
@Transactional
public class FreightTemplateServiceImpl extends ServiceImpl<FreightTemplateMapper, FreightTemplateDO> implements FreightTemplateService {

    @Autowired
    FreightTemplateExtendMapper freightTemplateExtendMapper;

    @Autowired
    GoodsMapper goodsMapper;

    /**
     * 商品sku管理mapper组件
     */
    @Autowired
    private GoodsSkuMapper goodsSkuMapper;

    @Autowired
    private RedisCache redisCache;

    private static final int FREIGHT_NAME_LENGTH = 30;

    /**
     * 添加运费模板
     *
     * @param dto
     */
    @Override
    public void insert(FreightTemplateDTO dto) {
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(dto == null);
        //保存运费模板主信息
        FreightTemplateDO po = new FreightTemplateDO();
        po.setRule(dto.getRule());
        po.setTemplateName(dto.getTemplateName());
        po.setCreater(dto.getCreater());
        po.setModifier(dto.getModifier());
        LocalDateTime now = LocalDateTime.now();
        po.setCreateTime(now);
        po.setUpdateTime(now);
        baseMapper.insert(po);
        //运费地区信息
        List<FreightTemplateExtendDO> pos = dto.getPos();
        if (pos != null && pos.size() > NumberConstant.NUMBER_ZERO) {
            pos.stream().forEach(poo -> {
                //按件数判断续件
                if (po.getRule() == 0) {
                    if (poo.getXnum() <= 0) {
                        throw new BaseException(new IResponseRxceptionCode(ResultEnum.FAIL.getCode(), StrUtil.format(ExceptionEnum.FAIL_FREIGHT_CONTINUE.getMessage(), "续件数量")));
                    }
                } else {
                    if (BigDecimal.ZERO.compareTo(poo.getXweight()) >= 0) {
                        throw new BaseException(new IResponseRxceptionCode(ResultEnum.FAIL.getCode(), StrUtil.format(ExceptionEnum.FAIL_FREIGHT_CONTINUE.getMessage(), "续重量")));
                    }
                }
                poo.setTemplateId(po.getId());
                poo.setCreater(dto.getCreater());
                poo.setModifier(dto.getModifier());
                poo.setCreateTime(now);
                poo.setUpdateTime(now);
                freightTemplateExtendMapper.insert(poo);
            });
        }
    }

    /**
     * 更新运费模板
     *
     * @param dto
     */
    @Override
    public void updateFt(FreightTemplateDTO dto) {
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(dto == null);
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(dto.getId() == null);
        //保存运费模板主信息
        FreightTemplateDO po = baseMapper.selectById(dto.getId());
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(po == null);
        po.setRule(dto.getRule());
        po.setTemplateName(dto.getTemplateName());
        po.setModifier(dto.getModifier());
        po.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(po);
        //先删除运费模板地区
        freightTemplateExtendMapper.delete(
                Wrappers.<FreightTemplateExtendDO>lambdaQuery()
                        .eq(FreightTemplateExtendDO::getTemplateId, dto.getId()));
        //重新保存运费地区信息
        List<FreightTemplateExtendDO> pos = dto.getPos();
        if (CollectionUtil.isNotEmpty(pos)) {
            pos.stream().forEach(poo -> {
                poo.setTemplateId(po.getId());
                poo.setCreater(dto.getCreater());
                poo.setModifier(dto.getModifier());
                poo.setCreateTime(po.getCreateTime());
                poo.setUpdateTime(po.getUpdateTime());
                freightTemplateExtendMapper.insert(poo);
            });
        }

        updateGoodsFtCache(dto.getId());
    }

    private void updateGoodsFtCache(Long id) {
        List<GoodsDO> goodsDoList = goodsMapper.selectList(
                Wrappers.<GoodsDO>lambdaQuery()
                        .eq(GoodsDO::getTransportId, id)
                        .eq(GoodsDO::getIsDel, StatusEnum.STATUS_NO.getCode()));

        List<Long> spuIdList=new ArrayList();
        goodsDoList.forEach(goodsDO -> spuIdList.add(goodsDO.getId()));

        //使用in查询需要判断集合是否为空
        if(CollectionUtil.isNotEmpty(spuIdList)) {
            LambdaQueryWrapper<GoodsSkuDO> goodsSkuWrapper = Wrappers.lambdaQuery();
            goodsSkuWrapper.in(GoodsSkuDO::getGoodsId, spuIdList);
            List<GoodsSkuDO> goodsSkus = goodsSkuMapper.selectList(goodsSkuWrapper);

            for (GoodsSkuDO goodsSkuDo : goodsSkus) {
                SkuDTO skuDto = new SkuDTO();
                skuDto.setId(goodsSkuDo.getId());
                skuDto.setGoodsId(goodsSkuDo.getGoodsId());
                skuDto.setGoodsName(goodsSkuDo.getGoodsName());
                skuDto.setSpecName(goodsSkuDo.getSpecName());
                skuDto.setGoodsPropertyImage(goodsSkuDo.getGoodsPropertyImage());
                skuDto.setSupplyId(goodsSkuDo.getSupplyId());
                skuDto.setGoodsPrice(goodsSkuDo.getGoodsPrice());
                skuDto.setPlatinumPrice(goodsSkuDo.getPlatinumPrice());
                skuDto.setDiamondsPrice(goodsSkuDo.getDiamondsPrice());
                skuDto.setKingPrice(goodsSkuDo.getKingPrice());
                skuDto.setGetOrderPrice(goodsSkuDo.getGetOrderPrice());
                skuDto.setGoodsCostprice(goodsSkuDo.getGoodsCostprice());
                skuDto.setGoodsGrossWeight(goodsSkuDo.getWeight());
                skuDto.setCateId(goodsSkuDo.getCateId());
                GoodsDO goodsDo = goodsMapper.selectById(skuDto.getGoodsId());
                FreightTempDTO freightTempDTO = freightInfo(goodsDo.getTransportId());
                skuDto.setFreightTempDTO(freightTempDTO);
                skuDto.setGoodsType(goodsDo.getGoodsType());
                skuDto.setDrainage(goodsDo.getIsYinliu());
                skuDto.setIsImport(goodsDo.getIsImport());
                skuDto.setGoodCountry(goodsDo.getGoodCountry());
                skuDto.setFixRebate(goodsDo.getFixRebate());
                //不发货地区
                skuDto.setNoDeliveryRegion(goodsDo.getNoDeliveryRegionId());
                redisCache.setCacheObject(GoodsKeyConstant.GOODS_SKU_KEY + skuDto.getId(), skuDto);
            }
        }
    }

    /**
     * 删除模板
     *
     * @param id       主键id
     * @param username 用户名
     */
    @Override
    public void delete(Long id, String username) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id == null);
        //判断商品是否应用模板
        int count = goodsMapper.selectCount(
                Wrappers.<GoodsDO>lambdaQuery()
                        .eq(GoodsDO::getTransportId, id)
                        .eq(GoodsDO::getIsDel, StatusEnum.STATUS_NO.getCode()));
        ExceptionEnum.FAIL_GOODS_FREIGHT_EXIST.doThrowIf(count > NumberConstant.NUMBER_ZERO);
        FreightTemplateDO po = baseMapper.selectById(id);
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(po == null);
        po.setIsDel(StatusEnum.STATUS_YES.getCode());
        po.setModifier(username);
        po.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(po);
    }

    /**
     * 获取运费地区信息
     *
     * @param id   主键id
     * @param type 运费规则,0按照数量,1按照重量
     * @return
     */
    @Override
    public List<FreightTemplateExtendVO> selectExtendsById(Long id, Integer type) {
        return freightTemplateExtendMapper.selectList(
                Wrappers.<FreightTemplateExtendDO>lambdaQuery()
                        .eq(FreightTemplateExtendDO::getTemplateId, id))
                .stream().map(p -> {
                    FreightTemplateExtendVO vo = null;
                    try {
                        vo = p.clone(FreightTemplateExtendVO.class);
//                        if(NumberConstant.NUMBER_ONE.intValue()==type){
//                            vo.setSwprice(vo.getSprice());
//                            vo.setSprice(vo.getSprice());
//                            vo.setXwprice(vo.getXprice());
//                            vo.setXprice(new BigDecimal(NumberConstant.NUMBER_ZERO));
//                        }
                    } catch (Exception e) {
                        ExceptionEnum.FAIL_CHANGE.newException();
                    }
                    return vo;
                }).collect(Collectors.toList());
    }

    /**
     * 获取运费模板详情
     *
     * @param id 主键id
     * @return
     */
    @Override
    public FreightTemplateDTO selectById(Long id) {
        FreightTemplateDTO dto = new FreightTemplateDTO();
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id == null);
        FreightTemplateDO po = baseMapper.selectById(id);
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(po == null);
        //运费模板信息
        dto.setId(po.getId());
        dto.setTemplateName(po.getTemplateName());
        dto.setCreateTime(po.getCreateTime());
        //运费地区信息
        dto.setFreightTemplateExtend(selectExtendsById(id, po.getRule()));
        dto.setRule(po.getRule());
        return dto;
    }

    /**
     * 复制模板信息
     *
     * @param id       主键id
     * @param username 操作用户
     */
    @Override
    public void cloneInfo(Long id, String username) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id == null);
        FreightTemplateDO po = baseMapper.selectById(id);
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(po == null);
        //校验运费模板长度
        ExceptionEnum.FAIL_FREIGHT_BIG_LENGTH.doThrowIf((po.getTemplateName() + "的副本").length() > FREIGHT_NAME_LENGTH);
        //运费模板信息
        FreightTemplateDO pos = new FreightTemplateDO();
        pos.setTemplateName(po.getTemplateName() + "的副本");
        pos.setCreateTime(LocalDateTime.now());
        pos.setUpdateTime(LocalDateTime.now());
        pos.setCreater(username);
        pos.setModifier(username);
        pos.setRule(po.getRule());
        baseMapper.insert(pos);
        //运费模板地区信息
        List<FreightTemplateExtendDO> freightTemplateExtends = freightTemplateExtendMapper.selectList(
                Wrappers.<FreightTemplateExtendDO>lambdaQuery()
                        .eq(FreightTemplateExtendDO::getTemplateId, id));
        freightTemplateExtends.stream().forEach(f -> {
            f.setId(null);
            f.setTemplateId(pos.getId());
            f.setCreateTime(pos.getCreateTime());
            f.setUpdateTime(pos.getUpdateTime());
            f.setModifier(username);
            f.setCreater(username);
            freightTemplateExtendMapper.insert(f);
        });
    }


    public FreightTempDTO freightInfo(Long id) {
        //获取模板信息
        FreightTemplateDO ftDO = baseMapper.selectOne(
                Wrappers.<FreightTemplateDO>lambdaQuery()
                        .eq(FreightTemplateDO::getId, id)
                        .eq(FreightTemplateDO::getIsDel, StatusEnum.STATUS_NO.getCode()));
        ExceptionEnum.FAIL_FREIGHT_NULL.doThrowIf(ftDO == null);
        //获取模板的详情
        List<FreightTemplateExtendDO> dos = freightTemplateExtendMapper.selectList(
                Wrappers.<FreightTemplateExtendDO>lambdaQuery()
                        .eq(FreightTemplateExtendDO::getTemplateId, id));
        return new FreightTempDTO(ftDO.getId(), ftDO.getTemplateName(), ftDO.getRule(), pos2Dtos(dos));
    }

    private List<FreightTempInfoDTO> pos2Dtos(List<FreightTemplateExtendDO> pos) {
        return pos.stream().map(po -> {
            FreightTempInfoDTO dto = null;
            try {
                dto = po.clone(FreightTempInfoDTO.class);
            } catch (Exception e) {

            }
            return dto;
        }).collect(Collectors.toList());
    }
}
